#include <QFontDialog>
#include <QDateTime>
#include <QTextStream>
#include "uart_interaction.h"
#include "uart_setting.h"
#include "ui_uart_interface.h"


namespace UartNamespace {
serial::serial(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::serial){
  ui->setupUi(this);
  ui->retranslateUi(this);

  uart_core_ = new Uartcore;

  QStringList serialStrList;
  serialStrList = uart_core_->UartPortScan();
  for (int i=0; i<serialStrList.size(); i++) {
     ui->portComboBox->addItem(serialStrList[i]);
  }

  ui->baudComboBox->setCurrentIndex(10);
  connect(uart_core_, SIGNAL(UartDataReadReadySignal()), this, SLOT(ReadUartData()));

  StatusBarInitialization();
}

serial::~serial(){
  uart_core_->UnInit();
  delete uart_core_;
  delete ui;
}

void serial::StatusBarInitialization(){
  QStatusBar* bar = ui->statusBar;
  rx_display_ = new QLabel;
  rx_display_->setMinimumSize(300,20);
  rx_display_->setFrameShape(QFrame::NoFrame);
  rx_display_->setFrameShadow(QFrame::Plain);
  rx_display_->setText(tr("RX")+": 0");
  rx_display_->setStyleSheet("QLabel { color : black; }");

  tx_display_ = new QLabel;
  tx_display_->setMinimumSize(300,20);
  tx_display_->setFrameShape(QFrame::NoFrame);
  tx_display_->setFrameShadow(QFrame::Plain);
  tx_display_->setText((tr("TX") + ": 0"));
  tx_display_->setStyleSheet("QLabel { color : black; }");

  connect_display_ = new QLabel;
  connect_display_->setMinimumSize(300,20);
  connect_display_->setFrameShape(QFrame::NoFrame);
  connect_display_->setFrameShadow(QFrame::Plain);
  connect_display_->setText(tr("Serial Port not connect"));
  connect_display_->setStyleSheet("QLabel { color : black; }");

  bar->addWidget(connect_display_);
  bar->addWidget(rx_display_);
  bar->addWidget(tx_display_);
}

void serial::on_send_lineEdit_returnPressed() {
  on_sendButton_clicked();
  ui->send_lineEdit->clear();
}

void serial::on_refreshButton_clicked() {
  ui->portComboBox->clear();
  QStringList serialStrList = uart_core_->UartPortScan();
  for (int i=0; i<serialStrList.size(); i++){
    ui->portComboBox->addItem(serialStrList[i]);
  }
}

std::string serial::ExtractParentheses(const std::string& str) {
    std::size_t start_pos = str.find('(');
    std::size_t end_pos = str.find(')');

    if (start_pos == std::string::npos || end_pos == std::string::npos || start_pos >= end_pos) {
        return "NULL";
    }

    return str.substr(start_pos + 1, end_pos - start_pos - 1);
}

void serial::on_openPortButton_clicked() {
  if (ui->portComboBox->currentText().isEmpty()) {
    PromptBoxOutputText(NO_SERIAL_PORT);
    return;
  }

  std::string uart_name = ExtractParentheses(ui->portComboBox->currentText().toStdString());
  if (uart_name.compare("NULL") == 0) {
    PromptBoxOutputText("uart name NULL");
    return;
  }

  if(is_the_serial_port_open_ == false) {
    if(uart_core_->open(QString::fromStdString(uart_name),
                      ui->baudComboBox->currentText().toInt(),
                      uart_core_->data_bits_,
                      uart_core_->parity_bits_,
                      uart_core_->stop_bits_,
                      uart_core_->flow_control_)) {
      // 关闭下拉列表使能
      ui->portComboBox->setEnabled(false);
      ui->baudComboBox->setEnabled(false);
      ui->refreshButton->setEnabled(false);
      ui->openPortButton_3->setEnabled(false);
      // 修改按钮名称
      ui->openPortButton->setText(tr("Close Port"));
      connect_display_->setText(tr("Port already opended"));
      connect_display_->setStyleSheet("QLabel { color : green; }");

      is_the_serial_port_open_ = true;
    }
  } else {
    // 关闭串口
    uart_core_->close();
    // 重新开启下拉列表使能
    ui->portComboBox->setEnabled(true);
    ui->baudComboBox->setEnabled(true);
    ui->refreshButton->setEnabled(true);
    ui->openPortButton_3->setEnabled(true);
    // 恢复按钮名称
    ui->openPortButton->setText(tr("Open Port"));
    connect_display_->setText(tr("Port already Closed"));
    connect_display_->setStyleSheet("QLabel { color : black; }");

    is_the_serial_port_open_ = false;
  }
}

void serial::on_sendButton_clicked(){
  QByteArray send_data;
  send_data = ui->send_lineEdit->text().toLatin1();
  if (ui->hexSendCheckBox->checkState()){
    send_data = uart_core_->HexStringToByteArray(send_data);
  }

  if (ui->checkBox_5->checkState()) {
    send_data += "\r\n";
  }

  if (send_data.length() <= 0) {
    ui->recvBrowser->append(tr("input error"));
    return;
  }

  tx_quantity_ += send_data.length();
  tx_display_->setText(tr("TX:")+QString::number(tx_quantity_,10));
  uart_core_->write(send_data);
}

void serial::PromptBoxOutputText(const QString &text){
    ui->recvBrowser->insertPlainText(text+"\n");
}

void serial::UartShowWithTimestamp(QByteArray &display_read_data) {
  // 获取当前时间戳
  QDateTime currentDateTime = QDateTime::currentDateTime();
  QString timestamp = currentDateTime.toString("yyyy-MM-dd hh:mm:ss") + " ";

  if (ui->hexRecvCheckBox->checkState()) {
    // 如果选中，显示十六进制数据
    QString hexData;
    for (int i = 0; i < display_read_data.size(); ++i) {
      hexData += QString::number(static_cast<unsigned char>(display_read_data[i]), 16).rightJustified(2, '0') + " ";
    }
    ui->recvBrowser->append(timestamp + hexData);
  } else {
    // 否则，显示原始数据
    QTextStream stream(display_read_data);
    QString line;
    while (!stream.atEnd()) {
      line = stream.readLine();
      ui->recvBrowser->append(timestamp + line);
    }
  }
}

// 读取从自定义串口类获得的数据
void serial::ReadUartData() {
  QByteArray read_data = uart_core_->UartBufferRead();
  QByteArray display_read_data = read_data.replace(char(0), "");
  //ui->recvTextEdit->moveCursor(QTextCursor::End);
  if (!show_timestamp_) {
    if(ui->hexRecvCheckBox->checkState()){
      ui->recvBrowser->append(display_read_data.toHex());
    } else {
      ui->recvBrowser->append(display_read_data);
    }
  } else {
    UartShowWithTimestamp(display_read_data);
  }
  rx_quantity_ += display_read_data.length();
  rx_display_->setText(tr("RX")+": "+QString::number(rx_quantity_,10));
  //ui->recvBrowser->moveCursor(QTextCursor::End); // 在末尾移动光标一格

  uart_core_->UartReadBufferClean();
}

void serial::on_clearTextButton_clicked(){
  ui->recvBrowser->clear();
  ui->recvBrowser->moveCursor(QTextCursor::Start);
  ui->send_lineEdit->clear();
  rx_display_->setText(tr("RX")+": 0");
  tx_display_->setText((tr("TX") + ": 0"));
}

void serial::on_actionExit_triggered(){
  QApplication* app = qApp;
  app->exit(0);
}

void serial::on_actionPreferences_triggered(){
  qDebug() << "on_actionPreferences_triggered:" << endl;
  bool ok;
  QFont font = QFontDialog::getFont(&ok, this->font(), this);
  if (ok) {
    ui->recvBrowser->setFont(font);
  }
}

void serial::on_actionShowTimestamp_triggered(){
  show_timestamp_ = !show_timestamp_;
  qDebug() << "on_actionShowTimestamp_triggered:" << show_timestamp_ << endl;
  if (show_timestamp_) {
    ui->recvBrowser->append("open show_timestamp");
  } else {
    ui->recvBrowser->append("close show_timestamp");
  }
}

void serial::on_openPortButton_3_clicked(){
  UartSetting uart_setting;

  uart_setting.UartSettingSetUartcore(uart_core_);
  uart_setting.AddAvailableSerialPortsToBox(uart_core_);
  uart_setting.exec();

  if(!uart_core_->serial_name_.isEmpty()){
    ui->portComboBox->setCurrentText(uart_core_->serial_name_);
  }

  QString string_baud_rate = QString::number(uart_core_->baud_rate_);
  qDebug() << "string_baud_rate:" << string_baud_rate;
  int index = ui->baudComboBox->findText(string_baud_rate);
  if (index == -1) {
    // 如果项不存在，则添加它
    ui->baudComboBox->addItem(string_baud_rate);
  }

  ui->baudComboBox->setCurrentText(string_baud_rate) ;
}

void serial::on_portComboBox_activated(const QString &arg1){
  uart_core_->serial_name_ = arg1;
}
}
